use std::string::FromUtf8Error;
#[derive(Clone)]
#[derive(Debug)]
pub struct HoString {
    hstr: String
}
impl HoString {
    #[allow(dead_code)]
    pub fn new() -> HoString {
        return HoString {
            hstr: String::new()
        };
    }
    #[allow(dead_code)]
    pub fn copy_str(s: &str) -> HoString {
        return HoString {
            hstr: s.to_string()
        };
    }
    #[allow(dead_code)]
    pub fn copy_string(s: String) -> HoString {
        return HoString {
            hstr: s
        };
    }
    pub fn to_bytes(&self) -> &[u8] {
        return self.hstr.as_bytes();
    }
    #[allow(dead_code)]
    pub fn to_str(&self) -> &str {
        return self.hstr.as_str();
    }

    #[allow(dead_code)]
    pub fn to_string(&self) -> String {
        return self.hstr.clone();
    }
    #[allow(dead_code)]
    pub fn push_char(&mut self, ch: char) {
        self.hstr.push(ch);
    }
    #[allow(dead_code)]
    pub fn push_byte(&mut self, b: u8) {
        let mut b_vec: Vec<u8> = Vec::new();
        b_vec.push(b);
        let byte_string: Result<String, FromUtf8Error> = String::from_utf8(b_vec);
        if let Ok(string) = byte_string {
            self.hstr.push_str(string.as_str());
        }
    }
    #[allow(dead_code)]
    pub fn push_str(&mut self, string: &str) {
        self.hstr.push_str(string);
    }
    #[allow(dead_code)]
    pub fn push_bytes(&mut self, bytes: &[u8]) {
        let byte_string: Result<String, FromUtf8Error> = String::from_utf8(bytes.to_vec());
        if let Ok(string) = byte_string {
            self.hstr.push_str(string.as_str());
        }
    }
    #[allow(dead_code)]
    pub fn length(&self) -> usize {
        return self.hstr.len();
    }
    #[allow(dead_code)]
    pub fn at(&self, index: usize) -> Option<char> {
        return self.to_str().chars().nth(index);
    }
    #[allow(dead_code)]
    pub fn byte_at(&self, index: usize) -> Option<u8> {
        if index >= self.length() {
            return None;
        } else {
            return Some(self.to_bytes()[index]);
        }
    }
    #[allow(dead_code)]
    pub fn mid(&self, index: usize, len: usize) -> &str {
        return &self.hstr.as_str()[index..index + len];
    }
    #[allow(dead_code)]
    pub fn mid_bytes(&self, index: usize, len: usize) -> &[u8] {
        return &self.to_bytes()[index..index + len];
    }
    #[allow(dead_code)]
    pub fn left(&self, len: usize) -> &str {
        return &self.hstr.as_str()[..len];
    }
    #[allow(dead_code)]
    pub fn left_bytes(&self, len: usize) -> &[u8] {
        return &self.to_bytes()[..len];
    }
    #[allow(dead_code)]
    pub fn right(&self, len: usize) -> &str {
        return &self.hstr.as_str()[self.hstr.len() - len..];
    }
    #[allow(dead_code)]
    pub fn right_bytes(&self, len: usize) -> &[u8] {
        return &self.to_bytes()[self.hstr.len() - len..];
    }
    #[allow(dead_code)]
    pub fn trim(&self) -> &[u8] {
        let len: usize = self.length();
        let mut left_index: usize = 0;
        let mut right_index: usize = len;
        loop {
            if left_index >= len {
                break;
            }
            if self.get(left_index) == ' ' ||
                self.get(left_index) == '\t' ||
                self.get(left_index) == '\r' ||
                self.get(left_index) == '\n' {
                left_index += 1;
            } else {
                break;
            }
        }
        loop {
            if right_index <= 0 {
                break;
            }
            if self.get(right_index) == ' ' ||
                self.get(right_index) == '\t' ||
                self.get(right_index) == '\r' ||
                self.get(right_index) == '\n' {
                right_index -= 1;
            } else {
                break;
            }
        }
        return self.mid_bytes(left_index, right_index - left_index - 1);
    }
    #[allow(dead_code)]
    pub fn compare_str(&self, string: &str) -> bool {
        if self.length() != string.len() {
            return false;
        } else {
            for i in 0..string.len() {
                let str_at: Option<char> = string.chars().nth(i);
                let self_at: Option<char> = self.at(i);
                let str_ch: char;
                let self_ch: char;
                match str_at {
                    Some(c) => str_ch = c,
                    None => return false
                }
                match self_at {
                    Some(c) => self_ch = c,
                    None => return false
                }
                if str_ch != self_ch {
                    return false;
                }
            }
            return true;
        }
    }
    #[allow(dead_code)]
    pub fn compare_bytes(&self, bytes: &[u8]) -> bool {
        if self.length() != bytes.len() {
            return false;
        } else {
            for i in 0..bytes.len() {
                let bytes_at: u8 = bytes[i];
                let self_at: Option<u8> = self.byte_at(i);
                let self_ch: u8;
                match self_at {
                    Some(c) => self_ch = c,
                    None => return false
                }
                if bytes_at != self_ch {
                    return false;
                }
            }
            return true;
        }
    }
    #[allow(dead_code)]
    pub fn get(&self, index: usize) -> char {
        let tmp: Option<char> = self.to_str().chars().nth(index);
        match tmp {
            Some(ch) => return ch,
            None => return '\0'
        }
    }
    #[allow(dead_code)]
    pub fn get_byte(&self, index: usize) -> u8 {
        if index >= self.length() {
            return 0;
        } else {
            return self.to_bytes()[index];
        }
    }
    #[allow(dead_code)]
    pub fn search_char(&self, ch: char, start: usize) -> i32 {
        if start >= self.length() {
            return -1;
        }
        for i in start..self.length() {
            if self.get(i) == ch {
                return i as i32;
            }
        }
        return -1;
    }
    #[allow(dead_code)]
    pub fn contains_char_vec(&self, chs: Vec<char>, start: usize) -> bool {
        if start >= self.length() {
            return false;
        }
        for i in start..self.length() {
            if chs.contains(&self.get(i)) {
                return true;
            }
        }
        return false;
    }
    #[allow(unused_assignments)]
    #[allow(dead_code)]
    pub fn split_str(&self, s: &str, times: isize) -> Vec<HoString> {
        let mut lines: Vec<HoString> = Vec::new();
        if self.length() == 0 || self.length() < s.len() {
            return lines;
        }
        let mut start: usize = 0;
        let mut index: i32 = self.search_str(s, start);
        let mut num: isize = times;
        while index != -1 && (num > 0 || num == -1) {
            let mut ho_s: HoString = HoString::new();
            ho_s.push_str(self.mid(start, index as usize - start));
            lines.push(ho_s);
            start = index as usize + s.len();
            index = self.search_str(s, start);
            if num > 0 {
                num -= 1;
            }
        }
        if start < self.length() {
            let mut ho_s: HoString = HoString::new();
            ho_s.push_str(self.mid(start, self.length() - start));
            lines.push(ho_s);
        }
        return lines;
    }
    #[allow(dead_code)]
    pub fn search_str(&self, string: &str, start: usize) -> i32 {
        if string.len() == 0 {
            return -1;
        } else if string.len() == self.length() {
            if self.compare_str(string) {
                return 0;
            } else {
                return -1;
            }
        } else if string.len() > self.length() {
            return -1;
        }
        let mut next: Vec<u32> = Vec::new();
        next.push(0);
        let mut _str: HoString = HoString::new();
        _str.push_str(string);
        for i in 1..string.len() {
            let mut next_len: u32 = 0;
            let mut next_max_len: u32 = 0;
            for len in 1..i + 1 {
                next_len += 1;
                let mut left: HoString = HoString::new();
                let left_str: &str = _str.left(len);
                left.push_str(left_str);
                let right_str: &str = _str.mid(i - len + 1, len);
                if left.compare_str(right_str) {
                    if next_max_len < next_len {
                        next_max_len = next_len;
                    }
                }
            }
            next.push(next_max_len);
        }
        let mut chars_i: usize = 0;
        let mut i: usize = start;
        while i < self.length() {
            if self.get(i) == _str.get(chars_i) {
                i += 1;
                chars_i += 1;
                if chars_i >= _str.length() {
                    return (i - chars_i) as i32;
                }
            } else {
                let next_op: Option<&u32> = next.get(chars_i);
                let next_item: usize;
                match next_op {
                    Some(item) => next_item = *item as usize,
                    None => return -1
                }
                if next_item > 0 {
                    chars_i = next_item - 1;
                } else {
                    chars_i = next_item;
                }
                if i + string.len() - chars_i >= self.length() + 1 {
                    break;
                }
                if self.get(i) == _str.get(chars_i) {
                    chars_i += 1;
                    if chars_i >= string.len() {
                        return (i - chars_i) as i32;
                    }
                }
                i += 1;
            }
        }
        return -1;
    }
    #[allow(unused_assignments)]
    #[allow(dead_code)]
    pub fn split_bytes(&self, s: &[u8], times: isize) -> Vec<HoString> {
        let mut lines: Vec<HoString> = Vec::new();
        if self.length() == 0 || self.length() < s.len() {
            return lines;
        }
        let mut start: usize = 0;
        let mut index: i32 = self.search_bytes(s, start);
        let mut num: isize = times;
        while index != -1 && (num > 0 || num == -1) {
            let mut ho_s: HoString = HoString::new();
            ho_s.push_bytes(self.mid_bytes(start, index as usize - start));
            lines.push(ho_s);
            start = index as usize + s.len();
            index = self.search_bytes(s, start);
            if num > 0 {
                num -= 1;
            }
        }
        if start < self.length() {
            let mut ho_s: HoString = HoString::new();
            ho_s.push_bytes(self.mid_bytes(start, self.length() - start));
            lines.push(ho_s);
        }
        return lines;
    }
    #[allow(dead_code)]
    pub fn search_bytes(&self, string: &[u8], start: usize) -> i32 {
        if string.len() == 0 {
            return -1;
        } else if string.len() == self.length() {
            if self.compare_bytes(string) {
                return 0;
            } else {
                return -1;
            }
        } else if string.len() > self.length() {
            return -1;
        }
        let mut next: Vec<u32> = Vec::new();
        next.push(0);
        let mut _str: HoString = HoString::new();
        _str.push_bytes(string);
        for i in 1..string.len() {
            let mut next_len: u32 = 0;
            let mut next_max_len: u32 = 0;
            for len in 1..i + 1 {
                next_len += 1;
                let mut left: HoString = HoString::new();
                let left_str: &[u8] = _str.left_bytes(len);
                left.push_bytes(left_str);
                let right_str: &[u8] = _str.mid_bytes(i - len + 1, len);
                if left.compare_bytes(right_str) {
                    if next_max_len < next_len {
                        next_max_len = next_len;
                    }
                }
            }
            next.push(next_max_len);
        }
        let mut chars_i: usize = 0;
        let mut i: usize = start;
        while i < self.length() {
            if self.get_byte(i) == _str.get_byte(chars_i) {
                i += 1;
                chars_i += 1;
                if chars_i >= _str.length() {
                    return (i - chars_i) as i32;
                }
            } else {
                let next_op: Option<&u32> = next.get(chars_i);
                let next_item: usize;
                match next_op {
                    Some(item) => next_item = *item as usize,
                    None => return -1
                }
                if next_item > 0 {
                    chars_i = next_item - 1;
                } else {
                    chars_i = next_item;
                }
                if i + string.len() - chars_i >= self.length() + 1 {
                    break;
                }
                if self.get_byte(i) == _str.get_byte(chars_i) {
                    chars_i += 1;
                    if chars_i >= string.len() {
                        return (i - chars_i) as i32;
                    }
                }
                i += 1;
            }
        }
        return -1;
    }
    #[allow(dead_code)]
    pub fn search_vec(&self, string_vec: Vec<&str>, start: usize) -> Vec<i32> {
        let mut ret_vec: Vec<i32> = Vec::new();
        let mut ret_type: Vec<bool> = Vec::new();
        for _ in 0..string_vec.len() {
            ret_vec.push(-1);
            ret_type.push(false);
        }
        let mut next_vec: Vec<Vec<u32>> = Vec::new();
        let mut str_vec: Vec<HoString> = Vec::new();
        for i in 0..string_vec.len() {
            let string_op: Option<&&str> = string_vec.get(i);
            let string: &str;
            match string_op {
                Some(x) => string = x,
                None => {
                    ret_vec.push(-1);
                    continue;
                }
            }
            if string.len() == 0 {
                ret_vec.push(-1);
                continue;
            } else if string.len() == self.length() {
                if self.compare_str(string) {
                    ret_vec.push(0);
                    continue;
                } else {
                    ret_vec.push(-1);
                    continue;
                }
            } else if string.len() > self.length() {
                ret_vec.push(-1);
                continue;
            }
            let mut next: Vec<u32> = Vec::new();
            next.push(0);
            let mut _str: HoString = HoString::new();
            _str.push_str(string);
            let mut _str_vec_item: HoString = HoString::new();
            _str_vec_item.push_str(string);
            str_vec.push(_str_vec_item);
            for i in 1..string.len() {
                let mut next_len: u32 = 0;
                let mut next_max_len: u32 = 0;
                for len in 1..i + 1 {
                    next_len += 1;
                    let mut left: HoString = HoString::new();
                    let left_str: &str = _str.left(len);
                    left.push_str(left_str);
                    let right_str: &str = _str.mid(i - len + 1, len);
                    if left.compare_str(right_str) {
                        if next_max_len < next_len {
                            next_max_len = next_len;
                        }
                    }
                }
                next.push(next_max_len);
            }
            next_vec.push(next);
        }
        let mut chars_i_vec: Vec<usize> = Vec::new();
        for _ in 0..next_vec.len() {
            chars_i_vec.push(0);
        }
        let mut i: usize = start;
        let mut j: usize;
        while i < self.length() {
            j = 0;
            let mut is_all_pass: bool = true;
            for k in 0..ret_type.len() {
                if let Some(x) = ret_type.get(k) {
                    if *x == false {
                        is_all_pass = false;
                        break;
                    }
                }
            }
            if is_all_pass {
                return ret_vec;
            }
            while j < next_vec.len() {
                let ret_type_op: Option<&bool> = ret_type.get(j);
                let _ret_type: bool;
                match ret_type_op {
                    Some(x) => _ret_type = *x,
                    None => {
                        chars_i_vec.remove(j);
                        continue;
                    }
                }
                if _ret_type {
                    j += 1;
                    continue;
                }
                let string_op: Option<&&str> = string_vec.get(j);
                let string: &str;
                match string_op {
                    Some(x) => string = x,
                    None => {
                        j += 1;
                        continue;
                    }
                }
                let next_op: Option<&Vec<u32>> = next_vec.get(j);
                let next: &Vec<u32>;
                match next_op {
                    Some(x) => next = x,
                    None => {
                        j += 1;
                        continue;
                    }
                }
                let mut ho_str: HoString = HoString::new();
                ho_str.push_str(string);
                let chars_i_op: Option<&usize> = chars_i_vec.get(j);
                let mut chars_i: usize;
                match chars_i_op {
                    Some(x) => chars_i = *x,
                    None => {
                        j += 1;
                        continue;
                    }
                }
                if self.get(i) == ho_str.get(chars_i) {
                    chars_i += 1;
                    chars_i_vec.remove(j);
                    chars_i_vec.insert(j, chars_i);
                    if chars_i >= ho_str.length() {
                        let index: i32 = i as i32 - chars_i as i32;
                        ret_vec.remove(j);
                        ret_vec.insert(j, index + 1);
                        ret_type.remove(j);
                        ret_type.insert(j, true);
                    }
                    j += 1;
                    continue;
                } else {
                    let next_op: Option<&u32> = next.get(chars_i);
                    let next_item: usize;
                    match next_op {
                        Some(item) => next_item = *item as usize,
                        None => {
                            ret_vec.push(-1);
                            chars_i_vec.remove(j);
                            continue;
                        }
                    }
                    if next_item > 0 {
                        chars_i = next_item - 1;
                    } else {
                        chars_i = next_item;
                    }
                    chars_i_vec.remove(j);
                    chars_i_vec.insert(j, chars_i);
                    if i + ho_str.length() - chars_i >= self.length() + 1 {
                        ret_type.remove(j);
                        ret_type.insert(j, true);
                        continue;
                    }
                    if self.get(i) == ho_str.get(chars_i) {
                        chars_i += 1;
                        chars_i_vec.remove(j);
                        chars_i_vec.insert(j, chars_i);
                        if chars_i >= ho_str.length() {
                            ret_vec.remove(j);
                            ret_vec.insert(j, (i - chars_i + 1) as i32);
                        }
                    }
                }
                j += 1;
            }
            i += 1;
        }
        return ret_vec;
    }
    #[allow(dead_code)]
    pub fn search_vec_one(&self, string_vec: Vec<&str>, start: usize) -> Vec<i32> {
        let mut ret_vec: Vec<i32> = Vec::new();
        let mut ret_type: Vec<bool> = Vec::new();
        for _ in 0..string_vec.len() {
            ret_vec.push(-1);
            ret_type.push(false);
        }
        let mut next_vec: Vec<Vec<u32>> = Vec::new();
        let mut str_vec: Vec<HoString> = Vec::new();
        for i in 0..string_vec.len() {
            let string_op: Option<&&str> = string_vec.get(i);
            let string: &str;
            match string_op {
                Some(x) => string = x,
                None => {
                    ret_vec.push(-1);
                    continue;
                }
            }
            if string.len() == 0 {
                ret_vec.push(-1);
                continue;
            } else if string.len() == self.length() {
                if self.compare_str(string) {
                    ret_vec.push(0);
                    continue;
                } else {
                    ret_vec.push(-1);
                    continue;
                }
            } else if string.len() > self.length() {
                ret_vec.push(-1);
                continue;
            }
            let mut next: Vec<u32> = Vec::new();
            next.push(0);
            let mut _str: HoString = HoString::new();
            _str.push_str(string);
            let mut _str_vec_item: HoString = HoString::new();
            _str_vec_item.push_str(string);
            str_vec.push(_str_vec_item);
            for i in 1..string.len() {
                let mut next_len: u32 = 0;
                let mut next_max_len: u32 = 0;
                for len in 1..i + 1 {
                    next_len += 1;
                    let mut left: HoString = HoString::new();
                    let left_str: &str = _str.left(len);
                    left.push_str(left_str);
                    let right_str: &str = _str.mid(i - len + 1, len);
                    if left.compare_str(right_str) {
                        if next_max_len < next_len {
                            next_max_len = next_len;
                        }
                    }
                }
                next.push(next_max_len);
            }
            next_vec.push(next);
        }
        let mut chars_i_vec: Vec<usize> = Vec::new();
        for _ in 0..next_vec.len() {
            chars_i_vec.push(0);
        }
        let mut i: usize = start;
        let mut j: usize;
        while i < self.length() {
            j = 0;
            let mut is_all_pass: bool = true;
            for k in 0..ret_type.len() {
                if let Some(x) = ret_type.get(k) {
                    if *x == false {
                        is_all_pass = false;
                        break;
                    }
                }
            }
            if is_all_pass {
                return ret_vec;
            }
            while j < next_vec.len() {
                let ret_type_op: Option<&bool> = ret_type.get(j);
                let _ret_type: bool;
                match ret_type_op {
                    Some(x) => _ret_type = *x,
                    None => {
                        chars_i_vec.remove(j);
                        continue;
                    }
                }
                if _ret_type {
                    j += 1;
                    continue;
                }
                let string_op: Option<&&str> = string_vec.get(j);
                let string: &str;
                match string_op {
                    Some(x) => string = x,
                    None => {
                        j += 1;
                        continue;
                    }
                }
                let next_op: Option<&Vec<u32>> = next_vec.get(j);
                let next: &Vec<u32>;
                match next_op {
                    Some(x) => next = x,
                    None => {
                        j += 1;
                        continue;
                    }
                }
                let mut ho_str: HoString = HoString::new();
                ho_str.push_str(string);
                let chars_i_op: Option<&usize> = chars_i_vec.get(j);
                let mut chars_i: usize;
                match chars_i_op {
                    Some(x) => chars_i = *x,
                    None => {
                        j += 1;
                        continue;
                    }
                }
                if self.get(i) == ho_str.get(chars_i) {
                    chars_i += 1;
                    chars_i_vec.remove(j);
                    chars_i_vec.insert(j, chars_i);
                    if chars_i >= ho_str.length() {
                        let index: i32 = i as i32 - chars_i as i32;
                        ret_vec.remove(j);
                        ret_vec.insert(j, index + 1);
                        return ret_vec;
                    }
                    j += 1;
                    continue;
                } else {
                    let next_op: Option<&u32> = next.get(chars_i);
                    let next_item: usize;
                    match next_op {
                        Some(item) => next_item = *item as usize,
                        None => {
                            ret_vec.push(-1);
                            chars_i_vec.remove(j);
                            continue;
                        }
                    }
                    if next_item > 0 {
                        chars_i = next_item - 1;
                    } else {
                        chars_i = next_item;
                    }
                    chars_i_vec.remove(j);
                    chars_i_vec.insert(j, chars_i);
                    if i + ho_str.length() - chars_i >= self.length() + 1 {
                        ret_type.remove(j);
                        ret_type.insert(j, true);
                        continue;
                    }
                    if self.get(i) == ho_str.get(chars_i) {
                        chars_i += 1;
                        chars_i_vec.remove(j);
                        chars_i_vec.insert(j, chars_i);
                        if chars_i >= ho_str.length() {
                            ret_vec.remove(j);
                            ret_vec.insert(j, (i - chars_i + 1) as i32);
                            return ret_vec;
                        }
                    }
                }
                j += 1;
            }
            i += 1;
        }
        return ret_vec;
    }
    #[allow(dead_code)]
    pub fn search_bytes_vec_one(&self, string_vec: Vec<&[u8]>, start: usize) -> Vec<i32> {
        let mut ret_vec: Vec<i32> = Vec::new();
        let mut ret_type: Vec<bool> = Vec::new();
        for _ in 0..string_vec.len() {
            ret_vec.push(-1);
            ret_type.push(false);
        }
        let mut next_vec: Vec<Vec<u32>> = Vec::new();
        let mut str_vec: Vec<HoString> = Vec::new();
        for i in 0..string_vec.len() {
            let string_op: Option<&&[u8]> = string_vec.get(i);
            let string: &[u8];
            match string_op {
                Some(x) => string = x,
                None => {
                    ret_vec.push(-1);
                    continue;
                }
            }
            if string.len() == 0 {
                ret_vec.push(-1);
                continue;
            } else if string.len() == self.length() {
                if self.compare_bytes(string) {
                    ret_vec.push(0);
                    continue;
                } else {
                    ret_vec.push(-1);
                    continue;
                }
            } else if string.len() > self.length() {
                ret_vec.push(-1);
                continue;
            }
            let mut next: Vec<u32> = Vec::new();
            next.push(0);
            let mut _str: HoString = HoString::new();
            _str.push_bytes(string);
            let mut _str_vec_item: HoString = HoString::new();
            _str_vec_item.push_bytes(string);
            str_vec.push(_str_vec_item);
            for i in 1..string.len() {
                let mut next_len: u32 = 0;
                let mut next_max_len: u32 = 0;
                for len in 1..i + 1 {
                    next_len += 1;
                    let mut left: HoString = HoString::new();
                    let left_str: &[u8] = _str.left_bytes(len);
                    left.push_bytes(left_str);
                    let right_str: &[u8] = _str.mid_bytes(i - len + 1, len);
                    if left.compare_bytes(right_str) {
                        if next_max_len < next_len {
                            next_max_len = next_len;
                        }
                    }
                }
                next.push(next_max_len);
            }
            next_vec.push(next);
        }
        let mut chars_i_vec: Vec<usize> = Vec::new();
        for _ in 0..next_vec.len() {
            chars_i_vec.push(0);
        }
        let mut i: usize = start;
        let mut j: usize;
        while i < self.length() {
            j = 0;
            let mut is_all_pass: bool = true;
            for k in 0..ret_type.len() {
                if let Some(x) = ret_type.get(k) {
                    if *x == false {
                        is_all_pass = false;
                        break;
                    }
                }
            }
            if is_all_pass {
                return ret_vec;
            }
            while j < next_vec.len() {
                let ret_type_op: Option<&bool> = ret_type.get(j);
                let _ret_type: bool;
                match ret_type_op {
                    Some(x) => _ret_type = *x,
                    None => {
                        chars_i_vec.remove(j);
                        continue;
                    }
                }
                if _ret_type {
                    j += 1;
                    continue;
                }
                let string_op: Option<&&[u8]> = string_vec.get(j);
                let string: &[u8];
                match string_op {
                    Some(x) => string = x,
                    None => {
                        j += 1;
                        continue;
                    }
                }
                let next_op: Option<&Vec<u32>> = next_vec.get(j);
                let next: &Vec<u32>;
                match next_op {
                    Some(x) => next = x,
                    None => {
                        j += 1;
                        continue;
                    }
                }
                let mut ho_str: HoString = HoString::new();
                ho_str.push_bytes(string);
                let chars_i_op: Option<&usize> = chars_i_vec.get(j);
                let mut chars_i: usize;
                match chars_i_op {
                    Some(x) => chars_i = *x,
                    None => {
                        j += 1;
                        continue;
                    }
                }
                if self.get_byte(i) == ho_str.get_byte(chars_i) {
                    chars_i += 1;
                    chars_i_vec.remove(j);
                    chars_i_vec.insert(j, chars_i);
                    if chars_i >= ho_str.length() {
                        let index: i32 = i as i32 - chars_i as i32;
                        ret_vec.remove(j);
                        ret_vec.insert(j, index + 1);
                        return ret_vec;
                    }
                    j += 1;
                    continue;
                } else {
                    let next_op: Option<&u32> = next.get(chars_i);
                    let next_item: usize;
                    match next_op {
                        Some(item) => next_item = *item as usize,
                        None => {
                            ret_vec.push(-1);
                            chars_i_vec.remove(j);
                            continue;
                        }
                    }
                    if next_item > 0 {
                        chars_i = next_item - 1;
                    } else {
                        chars_i = next_item;
                    }
                    chars_i_vec.remove(j);
                    chars_i_vec.insert(j, chars_i);
                    if i + ho_str.length() - chars_i >= self.length() + 1 {
                        ret_type.remove(j);
                        ret_type.insert(j, true);
                        continue;
                    }
                    if self.get_byte(i) == ho_str.get_byte(chars_i) {
                        chars_i += 1;
                        chars_i_vec.remove(j);
                        chars_i_vec.insert(j, chars_i);
                        if chars_i >= ho_str.length() {
                            ret_vec.remove(j);
                            ret_vec.insert(j, (i - chars_i + 1) as i32);
                            return ret_vec;
                        }
                    }
                }
                j += 1;
            }
            i += 1;
        }
        return ret_vec;
    }
    #[allow(dead_code)]
    pub fn replace_char(&self, ch: char, replace: &str, count: i32) -> HoString {
        if count < 1 && count != -1 {
            return self.clone();
        }
        let mut hstr: HoString = HoString::new();
        let mut count_i: i32 = 0;
        for i in 0..self.length() {
            count_i += 1;
            let current_ch: char = self.get(i);
            if current_ch == ch {
                hstr.push_str(replace);
            } else {
                hstr.push_char(current_ch);
            }
            if count > 0 && count_i >= count {
                break;
            }
        }
        return hstr;
    }
    #[allow(dead_code)]
    pub fn replace_str(&self, src: &str, replace: &str, count: i32) -> HoString {
        if count < 1 && count != -1 {
            return self.clone();
        }
        if src.len() == 0 {
            return self.clone();
        }
        let mut start: usize = 0;
        let mut count_i: i32 = 0;
        let mut i: isize = self.search_str(src, start) as isize;
        let mut ret_str: HoString = HoString::new();
        while i != -1 && (count_i <= count || count == -1) {
            let mid: &str = self.mid(start, (i - start as isize) as usize);
            count_i += 1;
            ret_str.push_str(mid);
            ret_str.push_str(replace);
            start += i as usize - start + src.len();
            if start as isize == i {
                start += 1;
            }
            i = self.search_str(src, start) as isize;
        }
        if start < self.length() {
            let right: &str = self.right(self.length() - start);
            ret_str.push_str(right);
        }
        return ret_str;
    }
    #[allow(dead_code)]
    pub fn replace_bytes(&self, src: &[u8], replace: &[u8], count: i32) -> HoString {
        if count < 1 && count != -1 {
            return self.clone();
        }
        if src.len() == 0 {
            return self.clone();
        }
        let mut start: usize = 0;
        let mut count_i: i32 = 0;
        let mut i: isize = self.search_bytes(src, start) as isize;
        let mut ret_str: HoString = HoString::new();
        while i != -1 && (count_i <= count || count == -1) {
            let mid: &[u8] = self.mid_bytes(start, (i - start as isize) as usize);
            count_i += 1;
            ret_str.push_bytes(mid);
            ret_str.push_bytes(replace);
            start += i as usize - start + src.len();
            if start as isize == i {
                start += 1;
            }
            i = self.search_bytes(src, start) as isize;
        }
        if start < self.length() {
            let right: &[u8] = self.right_bytes(self.length() - start);
            ret_str.push_bytes(right);
        }
        return ret_str;
    }
    #[allow(dead_code)]
    #[allow(unused_assignments)]
    pub fn replace_vec(&self, src_str_vec: Vec<&str>, replace_str_vec: Vec<&str>) -> HoString {
        let mut src: Vec<&str> = src_str_vec.clone();
        let mut replace: Vec<&str> = replace_str_vec.clone();
        if src.len() != replace.len() {
            return self.clone();
        }
        let mut src_type: Vec<bool> = Vec::new();
        for i in 0..src.len() {
            if let Some(x) = src.get(i) {
                if (*x).len() == 0 {
                    src.remove(i);
                    replace.remove(i);
                }
            }
            src_type.push(true);
        }
        let mut i_vec: Vec<i32> = self.search_vec_one(src.clone(), 0);
        let mut i: i32 = -1;
        let mut src_len: usize = 0;
        let mut replace_item: &str = "";
        for i_i in 0..i_vec.len() {
            if let Some(x) = i_vec.get(i_i) {
                if *x != -1 {
                    if let Some(y) = src.get(i_i) {
                        src_len = (*y).len();
                    }
                    if let Some(y) = replace.get(i_i) {
                        replace_item = *y;
                    }
                    i = *x;
                    break;
                }
            }
        }
        let mut start: usize = 0;
        let mut ret: HoString = HoString::new();
        while i != -1 {
            let mid: &str = self.mid(start, (i - start as i32) as usize);
            ret.push_str(mid);
            ret.push_str(replace_item);
            start += i as usize - start + src_len;
            i_vec = self.search_vec_one(src.clone(), start);
            let mut is_all_minusone: bool = true;
            for i_i in 0..i_vec.len() {
                if let Some(x) = i_vec.get(i_i) {
                    if *x != -1 {
                        is_all_minusone = false;
                        if let Some(y) = src.get(i_i) {
                            src_len = (*y).len();
                        }
                        if let Some(y) = replace.get(i_i) {
                            replace_item = *y;
                        }
                        i = *x;
                        break;
                    }
                }
            }
            if is_all_minusone {
                i = -1;
            }
        }
        if start < self.length() {
            let right: &str = self.right(self.length() - start);
            ret.push_str(right);
        }
        return ret;
    }
    #[allow(dead_code)]
    #[allow(unused_assignments)]
    pub fn replace_bytes_vec(&self, src_str_vec: Vec<&[u8]>, replace_str_vec: Vec<&[u8]>) -> HoString {
        let mut src: Vec<&[u8]> = src_str_vec.clone();
        let mut replace: Vec<&[u8]> = replace_str_vec.clone();
        if src.len() != replace.len() {
            return self.clone();
        }
        let mut src_type: Vec<bool> = Vec::new();
        for i in 0..src.len() {
            if let Some(x) = src.get(i) {
                if (*x).len() == 0 {
                    src.remove(i);
                    replace.remove(i);
                }
            }
            src_type.push(true);
        }
        let mut i_vec: Vec<i32> = self.search_bytes_vec_one(src.clone(), 0);
        let mut i: i32 = -1;
        let mut src_len: usize = 0;
        let mut replace_item: &[u8] = "".as_bytes();
        for i_i in 0..i_vec.len() {
            if let Some(x) = i_vec.get(i_i) {
                if *x != -1 {
                    if let Some(y) = src.get(i_i) {
                        src_len = (*y).len();
                    }
                    if let Some(y) = replace.get(i_i) {
                        replace_item = *y;
                    }
                    i = *x;
                    break;
                }
            }
        }
        let mut start: usize = 0;
        let mut ret: HoString = HoString::new();
        while i != -1 {
            let mid: &[u8] = self.mid_bytes(start, (i - start as i32) as usize);
            ret.push_bytes(mid);
            ret.push_bytes(replace_item);
            start += i as usize - start + src_len;
            i_vec = self.search_bytes_vec_one(src.clone(), start);
            let mut is_all_minusone: bool = true;
            for i_i in 0..i_vec.len() {
                if let Some(x) = i_vec.get(i_i) {
                    if *x != -1 {
                        is_all_minusone = false;
                        if let Some(y) = src.get(i_i) {
                            src_len = (*y).len();
                        }
                        if let Some(y) = replace.get(i_i) {
                            replace_item = *y;
                        }
                        i = *x;
                        break;
                    }
                }
            }
            if is_all_minusone {
                i = -1;
            }
        }
        if start < self.length() {
            let right: &[u8] = self.right_bytes(self.length() - start);
            ret.push_bytes(right);
        }
        return ret;
    }
}

